﻿#include <QToolTip>
#include <climits>
#include <qwt_scale_widget.h>
#include <qwt_plot_legenditem.h>
#include <qwt_plot_renderer.h>
#include <qwt_scale_engine.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_grid.h>
#include <qwt_symbol.h>
#include <qwt_legend.h>
#include <qwt_text.h>
#include <qwt_event_pattern.h>
#include "CQwtPlotWidget.h"
#include "CMyplotZoomers.h"

CQwtPlotWidget::CQwtPlotWidget(QQuickItem  *parent) : QQuickPaintedItem(parent)
{
    m_pQwtPlot = new QwtPlot();
    m_pCurvelMarker = new QwtPlotMarker();
    initQwtPlot(m_pQwtPlot);
    _slotUpdateAxis();
    setFlag(QQuickItem::ItemHasContents, true);
    setAcceptedMouseButtons (Qt::AllButtons);
    setAcceptHoverEvents(true);
    setAntialiasing(true);
    connect(this, &QQuickPaintedItem::widthChanged, this, &CQwtPlotWidget::_SlotUpdatePlotSize );
    connect(this, &QQuickPaintedItem::heightChanged, this, &CQwtPlotWidget::_SlotUpdatePlotSize );
    connect(this, &CQwtPlotWidget::SignalTitleInfoChanged, this, &CQwtPlotWidget::_SlotUpdateTitle);
    connect(this, &CQwtPlotWidget::signalAxisParameterChanged, this, &CQwtPlotWidget::_slotUpdateAxis);
    connect(this, &CQwtPlotWidget::signalLegendChanged, this, &CQwtPlotWidget::_slotUpdateLegend);
}

CQwtPlotWidget::~CQwtPlotWidget()
{
    delete m_pGrid;
    delete m_pPlotZoom;
    delete m_pQwtPlot;
    delete m_pCurvelMarker;
    if(m_pXAxis!=NULL)
    {
        delete m_pXAxis;
    }
    if(m_pYAxis!=NULL)
    {
        delete m_pYAxis;
    }
    QMapIterator<QString, QwtPlotCurve*> iterator(m_pPlotCurvelsMap);
    while (iterator.hasNext()) {
        iterator.next();
        delete iterator.value();   // 删除指针指向的QwtPlotCurve对象
    }
    m_pPlotCurvelsMap.clear();     // 清空QMap
}

void CQwtPlotWidget::paint(QPainter *painter)
{
    if (m_pQwtPlot) {
        QPixmap picture(boundingRect().size().toSize());
        QwtPlotRenderer renderer;
        renderer.renderTo(m_pQwtPlot, picture);
        painter->drawPixmap(QPoint(), picture);
        painter->drawRect(m_iZoomRectangleRect);
    }
}

void CQwtPlotWidget::_ReplotAndUpdate()
{
    m_pQwtPlot->updateLayout();
    m_pQwtPlot->replot();
    update();
}

void CQwtPlotWidget::initQwtPlot(QwtPlot* m_pQwtPlot)
{
    // m_pQwtPlot->setTitle("My Plot");
    m_pQwtPlot->setAutoReplot(false);
    m_pQwtPlot->setCanvasBackground( Qt::white );
    m_pQwtPlot->setFrameStyle(QFrame::NoFrame);
    m_pQwtPlot->setPalette(QColor(255, 255, 255));
    m_pQwtPlot->axisWidget(QwtPlot::yLeft)->setLayoutFlag(QwtScaleWidget::TitleHorizontal, true);
    m_pQwtPlot->setAxisScaleDraw(QwtPlot::yLeft, new CustomScaleDraw("Y", m_iYAxisDigit));  // 设置y轴的标签格式
    m_pQwtPlot->setAxisScaleDraw(QwtPlot::xBottom, new CustomScaleDraw("X", m_iXAxisDigit));  // 设置x轴的标签格式
    //添加网格线
    //设置y轴标题的角度为-90度
    m_pGrid = new QwtPlotGrid;
    m_pGrid->setPen("#f4f4f4", 2, Qt::SolidLine);//修改刻度线颜色
    m_pGrid->enableX(true); // 开启 x 轴的网格线
    m_pGrid->enableY(true); // 开启 y 轴的网格线
    m_pGrid->attach(m_pQwtPlot); // 添加到 plot 中
    m_pPlotZoom = new CMyPlotZoomers(m_pQwtPlot->canvas());
    _ReplotAndUpdate();
}

void CQwtPlotWidget::setXAxisName(const QString &title)
{
    m_strXAxisName = title;
    emit SignalTitleInfoChanged();
}

void CQwtPlotWidget::setYAxisName(const QString &title)
{
    m_strYAxisName = title;
    emit SignalTitleInfoChanged();
}

void CQwtPlotWidget::setCurveWidth(const double& width)
{
    QPen pen = m_pPlotCurvelsMap[m_strCurrentCurvelName]->pen();  // 获取当前画笔
    pen.setWidthF(width);       // 设置宽度
    m_pPlotCurvelsMap[m_strCurrentCurvelName]->setPen(pen);
    _ReplotAndUpdate();
}

void CQwtPlotWidget::setCurveWidth(const QString& curveName,const double& width)
{
    QPen pen = m_pPlotCurvelsMap[curveName]->pen();  // 获取当前画笔
    pen.setWidthF(width);       // 设置宽度
    m_pPlotCurvelsMap[curveName]->setPen(pen);
    _ReplotAndUpdate();
}

void CQwtPlotWidget::setCurveColor(const QString& curveName, const QColor &color)
{
    if(m_pPlotCurvelsMap.find(curveName)!=m_pPlotCurvelsMap.end())
    {
        QPen pen = m_pPlotCurvelsMap[curveName]->pen();  // 获取当前画笔
        pen.setColor(color);        // 设置颜色
        m_pPlotCurvelsMap[curveName]->setPen(pen);       // 更新画笔
        _ReplotAndUpdate();
    }
}

void CQwtPlotWidget::addCurve(const QString &curvelName)
{
    if(m_pPlotCurvelsMap.find(curvelName)==m_pPlotCurvelsMap.end())
    {
        QwtPlotCurve* curvel = new QwtPlotCurve(curvelName);
        QPen pen;
        pen.setWidth(m_iCurveWidth); // 设置线宽为2像素
        // 将这个笔应用到曲线上
        curvel->setPen(pen);
        m_pPlotCurvelsMap.insert(curvelName, curvel);
        ++m_iPlotCurveCount;
        if(!m_bSymbolVisible)
        {
            curvel->setSymbol(NULL);
        }
        else
        {
            QwtSymbol *symbol = new QwtSymbol(QwtSymbol::Ellipse,
                                              QColor(Qt::black),
                                              QColor(Qt::black),
                                              QSize(3, 3));
            curvel->setSymbol(symbol);
        }
        curvel->attach(m_pQwtPlot);
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::addPoint(const QString &curvelName, const double& x, const double& y, bool isUpdate)
{
    //_ShouldUpdateAxisRange(x,y);
    QVector<QPointF> samples;
    QPointF newPoint(x, y);
    if(m_pPlotCurvelsMap.find(curvelName)==m_pPlotCurvelsMap.end())
    {
        addCurve(curvelName);
    }else{
        auto points = m_pPlotCurvelsMap[curvelName]->data();// 获取所有点
        for (unsigned int i = 0; i < points->size(); ++i) {
            QPointF point = points->sample(i);
            if(point==newPoint)
            {
                return;
            }
            samples.append(point);
        }
    }
    samples.append(newPoint);
    m_pPlotCurvelsMap[curvelName]->setSamples(new QwtPointSeriesData(samples));
    m_pPlotCurvelsMap[curvelName]->setCurveAttribute(QwtPlotCurve::Fitted, m_bSmoothCurves);
    if(isUpdate)
    {
        _ReplotAndUpdate();
    }
}

void CQwtPlotWidget::addPoint(const QString &curvelName, const double& x,
                              const double& y, const QString &curvelType)
{
    addPoint(curvelName,x,y);
    if(curvelType=="散点图")
    {
        m_pPlotCurvelsMap[curvelName]->setStyle(QwtPlotCurve::Dots);
        setCurveWidth(curvelName, 3);
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::visibleCurve(const QString &strCurvelName, bool bVisible)
{
    if(m_pPlotCurvelsMap.find(strCurvelName)!=m_pPlotCurvelsMap.end())
    {
        if(bVisible)
            m_pPlotCurvelsMap[strCurvelName]->attach(m_pQwtPlot);
        else
            m_pPlotCurvelsMap[strCurvelName]->detach(); // 数据依然保留，但曲线从图表中移除
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::deleteCurveData()
{
    for(auto iter = m_pPlotCurvelsMap.begin(); iter != m_pPlotCurvelsMap.end(); iter++)
    {
        QwtPointSeriesData *oldData = dynamic_cast<QwtPointSeriesData *>(iter.value()->data());
        if(oldData!=NULL && oldData->size()!=0) {
            QVector<QPointF> emptyData;
            iter.value()->setSamples(new QwtPointSeriesData(emptyData)); // 会自动释放替换的曲线内存
        }
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::setLogScale()
{
    m_pYAxis = new QwtScaleDiv(m_pQwtPlot->axisScaleDiv(QwtPlot::yLeft));
    m_pQwtPlot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLogScaleEngine());
    _ReplotAndUpdate();                      // 重新绘制图形，以显示新增的点
}

void CQwtPlotWidget::setLinearScale()
{
    m_pQwtPlot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine());
    m_pQwtPlot->setAxisScaleDiv(QwtPlot::yLeft, *m_pYAxis);
    delete(m_pYAxis);
    m_pYAxis=NULL;
    _ReplotAndUpdate();
}

void CQwtPlotWidget::changeCurrentCurvel(const QString &curvelName)
{
    if(m_pPlotCurvelsMap.find(curvelName)!=m_pPlotCurvelsMap.end())
    {
        this->m_strCurrentCurvelName = curvelName;
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::changeShowLegend()
{
    if(m_pQwtPlot->legend())
    {
        m_pQwtPlot->insertLegend(NULL);
    }
    else{
        QwtLegend* legend = new QwtLegend();
        QFont font;
        font.setPointSize(m_iAxisSize); // 设置字体大小为12
        font.setFamily(m_strAxisFont);
        legend->setDefaultItemMode( QwtLegendData::Checkable );
        legend->setFont(font);
        m_pQwtPlot->insertLegend(legend, QwtPlot::TopLegend);
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::exportTECDataToCSV(const QString &strFileName)
{
    QFile file(strFileName+".csv");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "Cannot open file for writing";
        return;
    }

    QTextStream out(&file);
    // 写入列标题
    QString strXAxisName = m_strXAxisName!=""?m_strXAxisName:"X";
    QString strYAxisName = m_strYAxisName!=""?m_strYAxisName:"Y";
    for (auto key: m_pPlotCurvelsMap.keys())
    {
        out << key << ":"+strXAxisName+"," << key << ":"+strYAxisName+",";
    }
    out << "\n";

    // 获取所有曲线的点数的最大值
    size_t max = 0;
    for (auto curve : m_pPlotCurvelsMap.values())
    {
        if (curve->dataSize() > max)
            max = curve->dataSize();
    }

    // 遍历每个点
    for (size_t i = 0; i < max; ++i)
    {
        // 遍历每个曲线.
        for (auto curve: m_pPlotCurvelsMap.values())
        {
            if (i < curve->dataSize())
            {
                // 写入x和y值.
                out << curve->sample(i).x() << "," << curve->sample(i).y() << ",";
            }
            else
            {
                // 曲线没有更多的点，所以只写入逗号.
                out << ",,";
            }
        }
        out << "\n";
    }
    file.close();
}

void CQwtPlotWidget::exportFluoDataToCSV(const QString& strFilename)
{
    QFile bluefile(strFilename+"-blue.csv");
    QFile greenfile(strFilename+"-green.csv");
    QFile orangefile(strFilename+"-orange.csv");
    QFile redfile(strFilename+"-red.csv");
    if (!bluefile.open(QIODevice::WriteOnly | QIODevice::Text)||
            !greenfile.open(QIODevice::WriteOnly | QIODevice::Text)||
            !orangefile.open(QIODevice::WriteOnly | QIODevice::Text)||
            !redfile.open(QIODevice::WriteOnly | QIODevice::Text) )
    {
        qDebug() << "Cannot open file for writing";
        return;
    }

    QTextStream blueOut(&bluefile);
    QTextStream greenOut(&greenfile);
    QTextStream orangeOut(&orangefile);
    QTextStream redOut(&redfile);
    // 写入列标题
    QString strXAxisName = m_strXAxisName!=""?m_strXAxisName:"X";
    QString strYAxisName = m_strYAxisName!=""?m_strYAxisName:"Y";
    for (auto curve: m_pPlotCurvelsMap.values())
    {
        QString outputStr = curve->title().text() + ":" + strXAxisName + "," + curve->title().text() + ":" + strYAxisName + ",";

        QColor color = curve->pen().color();
        if(color == QColor("blue")) {
            blueOut << outputStr;
        }
        else if(color == QColor("green")) {
            greenOut << outputStr;
        }
        else if(color == QColor("orange")) {
            orangeOut << outputStr;
        }
        else if(color == QColor("red")) {
            redOut << outputStr;
        }
    }
    blueOut << "\n";
    greenOut << "\n";
    orangeOut << "\n";
    redOut << "\n";

    // 获取所有曲线的点数的最大值
    size_t max = 0;
    for (auto curve : m_pPlotCurvelsMap.values())
    {
        if (curve->dataSize() > max)
            max = curve->dataSize();
    }

    // 遍历每个点
    for (size_t i = 0; i < max; ++i)
    {
        // 遍历每个曲线
        for (auto curve: m_pPlotCurvelsMap.values())
        {
            QColor color = curve->pen().color();
            QTextStream* out = NULL;
            if(color == QColor("blue"))
                out = &blueOut;
            else if(color == QColor("green"))
                out = &greenOut;
            else if(color == QColor("orange"))
                out = &orangeOut;
            else if(color == QColor("red"))
                out = &redOut;

            if (i < curve->dataSize())
            {
                // 写入x和y值
                *out << curve->sample(i).x() << "," << curve->sample(i).y() << ",";
            }
            else
            {
                // 曲线没有更多的点，所以只写入逗号
                *out << ",,";
            }
        }
        blueOut << "\n";
        greenOut << "\n";
        orangeOut << "\n";
        redOut << "\n";
    }
    bluefile.close();
    greenfile.close();
    orangefile.close();
    redfile.close();
}

void CQwtPlotWidget::importDataFromCSV(const QString& strUrl)
{
    QUrl fileUrl(strUrl);
    QString strLocalPath = fileUrl.toLocalFile();
    QFile file(strLocalPath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Cannot open file for reading";
        return;
    }

    QTextStream in(&file);

    // 读取列标题
    QStringList titleList = in.readLine().split(",");
    int curveCount = titleList.size() / 2;

    QList<QVector<double>> xValuesLists;
    QList<QVector<double>> yValuesLists;
    for(int i = 0; i < curveCount; i++)
    {
        xValuesLists.append(QVector<double>());
        yValuesLists.append(QVector<double>());
    }
    QString line = in.readLine();
    while (!line.isNull())
    {
        QStringList fields = line.split(",");
        for (int i = 0; i < curveCount; ++i)
        {
            if (fields.at(i * 2).isEmpty() || fields.at(i * 2 + 1).isEmpty())
            {
                continue;  // 跳过空的元素
            }
            double x = fields.at(i * 2).toDouble();
            double y = fields.at(i * 2 + 1).toDouble();
            xValuesLists[i].push_back(x);
            yValuesLists[i].push_back(y);
        }
        line = in.readLine();
    }

    for (int i = 0; i < curveCount; ++i)
    {
        QString curveName = titleList.at(i * 2).split(":")[0];
        if (!m_pPlotCurvelsMap.contains(curveName))
        {
            qDebug() << "Curve does not exist";
            return;

        }
        for (int j = 0; j < xValuesLists[i].size(); ++j)
        {
            double x = xValuesLists[i][j];
            double y = yValuesLists[i][j];

            addPoint(curveName, x, y);
        }
    }
    file.close();
    _ReplotAndUpdate();
}

QColor CQwtPlotWidget::pointColor()
{
    return this->m_iPointColor;
}

void CQwtPlotWidget::setPointColor(const QColor& m_iPointColor)
{
    this->m_iPointColor = m_iPointColor;
}

void CQwtPlotWidget::setAxisFont(const QString& strAxisFont)
{
    m_strAxisFont = strAxisFont;
    emit SignalTitleInfoChanged();
}

void CQwtPlotWidget::setAxisSize(const int& iAxisSize)
{
    m_iAxisSize = iAxisSize;
    emit SignalTitleInfoChanged();
}

void CQwtPlotWidget::setSymbolVisible(bool bVisible)
{
    m_bSymbolVisible = bVisible;
    if(!bVisible)
    {
        for(auto &curve : m_pPlotCurvelsMap) {
            curve->setSymbol(NULL);
        }
        _ReplotAndUpdate();
    }
    else
    {
        QwtSymbol *symbol = new QwtSymbol(QwtSymbol::Ellipse,
                                          QColor(Qt::black),
                                          QColor(Qt::black),
                                          QSize(3, 3));
        for(auto &curve : m_pPlotCurvelsMap) {
            curve->setSymbol(symbol);
        }
        _ReplotAndUpdate();
    }
}

void CQwtPlotWidget::setSmoothCurves(bool bSmoothCurves)
{
    m_bSmoothCurves = bSmoothCurves;
    for(auto &curve : m_pPlotCurvelsMap) {
        curve->setCurveAttribute(QwtPlotCurve::Fitted, bSmoothCurves);
    }
    _ReplotAndUpdate();
}

void CQwtPlotWidget::setModel(const QVariant &model)
{
    if (model.type() == QVariant::Int) {
        int iCurveNumber =model.toInt();
        for(int i=1; i<=iCurveNumber; i++)
        {
            addCurve(QString::number(i));
        }
    }
    else if (model.canConvert<QVariantList>()) {
        QVariantList vCurveNameList = model.toList();
        for (const QVariant& variant : vCurveNameList) {
            addCurve(variant.toString());
        }
    }

}

void CQwtPlotWidget::setXAxisDigit(int xAxisDigit)
{
    m_iXAxisDigit = xAxisDigit;
    m_pQwtPlot->setAxisScaleDraw(QwtPlot::xBottom, new CustomScaleDraw("X", m_iXAxisDigit));  // 设置x轴的标签格式
}

void CQwtPlotWidget::setYAxisDigit(int yAxisDigit)
{
    m_iYAxisDigit = yAxisDigit;
    m_pQwtPlot->setAxisScaleDraw(QwtPlot::yLeft, new CustomScaleDraw("Y", m_iYAxisDigit));  // 设置x轴的标签格式
}


void CQwtPlotWidget::_ShouldUpdateAxisRange(const double& x, const double& y)
{
    bool axisChanged = false;

    if (x < m_dXMin) {
        m_dXMin = x/2;
        axisChanged = true;
    }
    if (x > m_dXMax) {
        m_dXMax = x*2;
        axisChanged = true;
    }
    if (y < m_dYMin) {
        m_dYMin = y/2;
        axisChanged = true;
    }
    if (y > m_dYMax) {
        m_dYMax = y*2;
        axisChanged = true;
    }

    if (axisChanged) {
        emit signalAxisParameterChanged();
    }
}

void CQwtPlotWidget::_SetAxisRange(QwtPlot::Axis axis, double dMinValue, double dMaxValue, bool bUpdateTickCount)
{
    double oldMin = m_pQwtPlot->axisScaleDiv(axis).lowerBound();
    double oldMax = m_pQwtPlot->axisScaleDiv(axis).upperBound();
    if(oldMin!=dMinValue||oldMax!=dMaxValue||bUpdateTickCount)
    {
        QwtScaleDiv xScaleDiv(dMinValue, dMaxValue);
        QList<double> xMajorTicks;
        for (double val = dMinValue; val <= dMaxValue; val += ((dMaxValue - dMinValue) / m_iXTickCount)) {
            xMajorTicks.append(val);
        }
        xScaleDiv.setTicks(QwtScaleDiv::MajorTick, xMajorTicks);
        m_pQwtPlot->setAxisScaleDiv(axis, xScaleDiv);
    }
}

void CQwtPlotWidget::mousePressEvent(QMouseEvent *event)
{
    if(m_dClosestPointX!=-1&&m_dClosestPointY!=-1&&!m_strClosestCurveName.isEmpty())
        emit(signalGetClosestPointValue(m_strClosestCurveName, m_dClosestPointX,m_dClosestPointY));
    if (!m_bZoomEnabled)
        return;
    m_iZoomRectangleRect.setTopLeft(event->pos());
    m_iZoomRectangleRect.setBottomRight(event->pos());
    m_pPlotZoom->widgetMousePressEvent(event);
    _ReplotAndUpdate();
}

void CQwtPlotWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (!m_bZoomEnabled)
        return;
    if(event->x()>m_iZoomRectangleRect.x())
    {//往右划
        if(m_pXAxis==NULL&&m_pYAxis==NULL)
        {
            m_pPlotZoom->setZoomBase(true);
            m_pXAxis = new QwtScaleDiv(m_pQwtPlot->axisScaleDiv(QwtPlot::xBottom));
            m_pYAxis = new QwtScaleDiv(m_pQwtPlot->axisScaleDiv(QwtPlot::yLeft));
        }
        m_pPlotZoom->widgetMouseReleaseEvent(event);
    }
    else if(event->x()<m_iZoomRectangleRect.x()){//往左滑
        if(m_pXAxis!=NULL)
        {
            m_pPlotZoom->widgetMouseReleaseEvent(event);
            m_pQwtPlot->setAxisScaleDiv(QwtPlot::xBottom, *m_pXAxis);
            m_pQwtPlot->setAxisScaleDiv(QwtPlot::yLeft, *m_pYAxis);
            delete(m_pXAxis);
            delete(m_pYAxis);
            m_pXAxis=NULL;
            m_pYAxis=NULL;
        }
    }
    m_dXMin = m_pQwtPlot->axisScaleDiv(QwtPlot::xBottom).lowerBound();
    m_dXMax = m_pQwtPlot->axisScaleDiv(QwtPlot::xBottom).upperBound();
    m_dYMin = m_pQwtPlot->axisScaleDiv(QwtPlot::yLeft).lowerBound();
    m_dYMax = m_pQwtPlot->axisScaleDiv(QwtPlot::yLeft).upperBound();
    emit signalAxisParameterChanged();
    m_iZoomRectangleRect = QRect();  // 清空m_iZoomRectangleRect
    _ReplotAndUpdate();
}

void CQwtPlotWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (!m_bZoomEnabled)
        return;
    m_iZoomRectangleRect.setBottomRight(event->pos());
    m_pPlotZoom->widgetMouseMoveEvent(event);
    _ReplotAndUpdate();
}

void CQwtPlotWidget::hoverMoveEvent(QHoverEvent *event)
{
    double minDist = 0.0;
    QList<QwtPlotItem*> items = m_pQwtPlot->itemList(QwtPlotItem::Rtti_PlotCurve);
    qint32 indexMin=-1;
    qint32 minValue=15;
    QwtPlotItem *itemCurve=NULL;
    for(QwtPlotItem *item : items){
        QwtPlotCurve *curve = static_cast<QwtPlotCurve *>(item);
        if(curve->dataSize() > 0)
        {
            qint32 index = curve->closestPoint(event->pos(), &minDist);
            if(minDist<minValue&&index>=0)
            {
                minValue=minDist;
                itemCurve = item;
                indexMin = index;
            }
        }
    }
    if(indexMin!=-1)
    {
        QwtPlotCurve *curve = static_cast<QwtPlotCurve *>(itemCurve);
        QMapIterator<QString, QwtPlotCurve*> iter(m_pPlotCurvelsMap);
        while (iter.hasNext()) {
            iter.next();
            if (iter.value() == curve) {
                m_strClosestCurveName = iter.key();  // 找到对应的QString
                break;
            }
        }
        QPointF closest_point = curve->sample(indexMin);
        m_dClosestPointX = closest_point.x();
        m_dClosestPointY = closest_point.y();
        m_pCurvelMarker->setValue(closest_point);
        m_pCurvelMarker->setSymbol(new QwtSymbol(QwtSymbol::Ellipse, QColor(this->m_iPointColor),
                                                 QPen(Qt::black, 2), QSize(10, 10))); // 设置点的形状、填充颜色、边框颜色和粗细、点的大小
        QPoint pos = mapToGlobal(event->pos()).toPoint();
        QToolTip::showText(pos, QString("(%1, %2, %3)").arg(m_strClosestCurveName).arg(m_dClosestPointX).arg(m_dClosestPointY), 0, QRect(), -1);
        // 在 plot 中显示 marker
        m_pCurvelMarker->attach(m_pQwtPlot);
    }
    else{
        QToolTip::hideText();
        m_pCurvelMarker->attach(NULL);
        m_dClosestPointX = -1;
        m_dClosestPointY = -1;
        m_strClosestCurveName = "";
    }
    indexMin=-1;
    _ReplotAndUpdate();
}

void CQwtPlotWidget::_SlotUpdatePlotSize()
{
    if (m_pQwtPlot) {
        m_pQwtPlot->setGeometry(0, 0, static_cast<int>(width()), static_cast<int>(height()));
    }
}

void CQwtPlotWidget::_SlotUpdateTitle()
{
    QFont font;
    font.setFamily(m_strAxisFont);
    font.setPointSize(m_iAxisSize); // 设置字体大小为12
    QwtText xTitle;
    xTitle.setFont(font); // 设置字体
    xTitle.setText(m_strXAxisName);
    m_pQwtPlot->setAxisTitle(QwtPlot::xBottom, xTitle);
    QwtText yTitle;
    yTitle.setFont(font); // 设置字体
    yTitle.setText(m_strYAxisName);
    m_pQwtPlot->setAxisTitle(QwtPlot::yLeft, yTitle);
    _ReplotAndUpdate();
}

void CQwtPlotWidget::_slotUpdateAxis()
{
    _SetAxisRange(QwtPlot::xBottom, m_dXMin, m_dXMax);
    _SetAxisRange(QwtPlot::yLeft, m_dYMin, m_dYMax);
    _ReplotAndUpdate();
}

void CQwtPlotWidget::_slotUpdateLegend()
{
    if(m_bShowLegend)
    {
        QwtLegend* legend = new QwtLegend();
        QFont font;
        font.setPointSize(m_iAxisSize); // 设置字体大小为12
        font.setFamily(m_strAxisFont);
        legend->setDefaultItemMode( QwtLegendData::Checkable );
        legend->setFont(font);
        m_pQwtPlot->insertLegend(legend, QwtPlot::TopLegend);
    }
    else{
        if(m_pQwtPlot->legend())
        {
            m_pQwtPlot->insertLegend(NULL);
        }
    }
    _ReplotAndUpdate();
}
